/**
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { computed, defineComponent, ref, SetupContext, watch } from 'vue';
import { NotifyButton, NotifyData } from '../notify.props';
import { ToastProps, toastProps } from './toast.props';

import './toast.css';

export default defineComponent({
    name: 'Toast',
    props: toastProps,
    emits: ['close', 'click'] as (string[] & ThisType<void>) | undefined,
    setup: (props: ToastProps, context: SetupContext) => {
        const animateIn = ref(props.animate);
        const animateEnd = 'fadeOut';
        const toast = computed(() => {
            return props.options as NotifyData;
        });
        const showingToast = ref(false);

        const toastClass = computed(() => {
            const classObject = {
                animated: showingToast.value,
                toast: true
            } as any;
            classObject[props.animate] = false;
            classObject[animateEnd] = showingToast.value;
            classObject[toast.value.type] = true;
            if (toast.value.theme) {
                classObject[toast.value.theme] = true;
            }
            return classObject;
        });

        const toastIconClass = computed(() => {
            const hasSpecialToastType = toast.value && toast.value.type;
            const iconType = hasSpecialToastType ? toast.value.type.replace('toasty-type-', '') : 'default';
            const iconTypeName = `f-icon-${iconType}`;
            const classObject = { 'f-icon': true } as any;
            classObject[iconTypeName] = true;
            return classObject;
        });

        const shouldShowTips = computed(() => toast.value.title || toast.value.msg);

        const shouldShowTitle = computed(() => toast.value.title && toast.value.msg);

        const shouldShowMessageOnly = computed(() => !toast.value.title && toast.value.msg);

        const shouldShowCloseButton = computed(() => {
            return true;
        });

        const shouldShowButtonsInTitle = computed(() => !!toast.value.buttons || !!context.slots.default);

        function onCloseToast($event: Event) {
            $event.stopPropagation();
            $event.preventDefault();
            showingToast.value = false;
            setTimeout(() => {
                context.emit('close', toast.value);
            }, 200);
        }

        function onClickButton($event: Event, notifyButton: NotifyButton) {}

        function getNotifyButtonClass(notifyButton: NotifyButton) {
            return `f-preten-link ${notifyButton.customClass ? notifyButton.customClass : ''}`;
        }

        watch(animateIn, () => {
            const animateInClass = animateIn.value || 'bounceInRight';
            const animateOutClass = 'fadeOut';
        });

        const renderNotifyButtons = () => {
            return (
                <>
                    <div class="after-toast-msg text-right">
                        {!context.slots.default &&
                            toast.value.buttons?.map((notifyButton: NotifyButton) => {
                                return (
                                    <span
                                        class={getNotifyButtonClass(notifyButton)}
                                        onClick={($event) => onClickButton($event, notifyButton)}>
                                        {notifyButton.text}
                                    </span>
                                );
                            })}
                        {context.slots.default && context.slots.default()}
                    </div>
                </>
            );
        };

        return () => {
            return (
                <div class={toastClass.value}>
                    {shouldShowCloseButton.value && (
                        <button title="close" class="toast-close f-btn-icon f-bare" onClick={onCloseToast}>
                            <span class="f-icon modal_close"></span>
                        </button>
                    )}
                    {shouldShowTips.value && (
                        <section class="modal-tips">
                            <div class="float-left modal-tips-iconwrap">
                                <span class={toastIconClass}></span>
                            </div>
                            <div class="modal-tips-content">
                                {shouldShowTitle.value && (
                                    <>
                                        <h5 class="toast-title modal-tips-title" v-html={toast.value.title}></h5>
                                        <p class="toast-msg" v-html={toast.value.msg}></p>
                                        {shouldShowButtonsInTitle.value && renderNotifyButtons()}
                                    </>
                                )}
                                {shouldShowMessageOnly.value &&
                                    (toast.value.buttons ? (
                                        <div class="toast-title-btns-wrapper d-flex">
                                            <h5 class="toast-title modal-tips-title only-toast-msg" v-html={toast.value.msg}></h5>
                                            <div class="after-toast-title text-right ml-auto">{renderNotifyButtons()}</div>
                                        </div>
                                    ) : (
                                        <h5 class="toast-title modal-tips-title only-toast-msg" v-html={toast.value.msg}></h5>
                                    ))}
                            </div>
                        </section>
                    )}
                </div>
            );
        };
    }
});
